﻿#ifndef XZIP_H
#define XZIP_H
#include<vector>
#include<string>
#include<fstream>
#include"XHuffmanTree.h"
#include"XZip_macro.h"
//压缩算法
class XZip
{
public:
	XZip()=default;
	~XZip()=default;
public://压缩
	//设置目录名字
	void setDirectory(std::string name);
	//添加文件
	void addFile(std::string name, const char* file, const size_t size);
	//添加文件
	void addFile(std::string filePath);
	//压缩储存到内存
	XZipData& gzip();
	//压缩储存到文件
	size_t gzip(std::string gzipfile);
public://解压
	//内存数据解压到内存
	size_t unzip(const char* data/*压缩数据*/, const size_t size/*大小*/);
	//内存数据解压到内存
	size_t unzip(const XZipData& data);
	//内存数据解压到文件目录
	size_t unzip(const char* data/*压缩数据*/, const size_t size/*大小*/,const std::string& writePath);
	//内存数据解压到文件目录
	size_t unzip(const XZipData& data, const std::string& writePath);
	//文件解压到内存数据
	size_t unzip(const std::string& File);
	//文件解压到目录
	size_t unzip(const std::string& File,std::string path);
public://获取信息
	//获取目录名字
	const std::string& directory();
	//获取压缩后的数据
	XZipData& gzipData();
	//获取解压后的数据
	const std::vector<Info>& unzipDatas();
	//清空
	void clear();
protected:
    //添加待压缩文件数据形成字典
	void setGZipDictionaries();
protected:
	//在压缩数据中写入字典
	size_t writeGZipDictionaries();
	//在压缩数据中写入目录信息
	void writeGZipDirectoryInof();
	//在压缩数据中写入文件信息
	void writeGZipFileInfo(const size_t nSel);
	//在压缩数据中写入文件数据
	void writeGZipFileData(const size_t nSel);
	//在压缩数据中写入压缩数据
	void writeGZipData(const char* data/*待压缩数据*/, const size_t size/*待压缩数据大小*/);
protected:
	//在压缩文件中写入压缩数据
	void writeGZipFileData(const size_t nSel, std::fstream& file);
	//在压缩文件中写入压缩数据
	void writeGZipData(std::fstream& writeFile, std::fstream& readFile);
protected:
	//读取压缩后的数据//构建字典
	size_t readGZipDictionaries(const char* data, const size_t size, size_t offset = 0);
	//读取目录信息
	size_t readGZipDirectoryInof(const char* data, const size_t size, size_t offset);
	//读取文件信息
	size_t readGZipFileInfo(const char* data, const size_t size, size_t offset);
	//获取解压后的数据
	size_t readUnZipData(const char* data, const size_t size, size_t offset, size_t count, std::vector<char>& unZipData);
protected:
	//从文件读取压缩后的数据//构建字典
	size_t readGZipDictionaries(std::fstream& readFile);
	//从文件读取读取目录信息
	size_t readGZipDirectoryInof(std::fstream& readFile);
	//从文件读取文件信息
	size_t readGZipFileInfo(std::fstream& readFile);
	//从文件读取获取解压后的数据
	size_t readUnZipData(std::fstream& readFile, size_t count, std::vector<char>& unZipData);
	//从文件读取获取解压后的数据
	size_t readUnZipData(std::fstream& readFile, size_t count, std::fstream& writeFile);
protected:
	XHuffmanTree tree;//哈夫曼树
	unsigned char m_Type=0;//存储类型
	XZipData m_zipData;//压缩的数据
	std::string m_DirectoryName;//当前目录名字
	std::vector<Info>m_file;//文件列表
	size_t m_fileSize=0;//文件数量
	size_t m_file_nSel = 0;//当前文件索引
	size_t m_readOffset = 0;//读取的文件偏移量
};

#endif // !XZIP_H
